package cn.botter.subject.domain.service.impl;

import cn.botter.subject.common.entity.PageResult;
import cn.botter.subject.common.enums.IsDeletedEnum;
import cn.botter.subject.domain.convert.SubjectInfoConverter;
import cn.botter.subject.domain.entity.SubjectInfoBO;
import cn.botter.subject.domain.handler.subject.SubjectTypeHandler;
import cn.botter.subject.domain.handler.subject.SubjectTypeHandlerFactory;
import cn.botter.subject.domain.service.SubjectDomainInfoService;
import cn.botter.subject.infra.basic.entity.*;
import cn.botter.subject.infra.basic.service.*;
import cn.botter.subject.infra.entity.UserInfo;
import cn.botter.subject.infra.rpc.UserRpc;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SubjectDomainInfoServiceImpl implements SubjectDomainInfoService {

    @Resource
    private SubjectInfoService subjectInfoService;
    @Resource
    private SubjectTypeHandlerFactory subjectTypeHandlerFactory;
    @Resource
    private SubjectMappingService subjectMappingService;
    @Resource
    private SubjectBriefService subjectBriefService;
    @Resource
    private SubjectLabelService subjectLabelService;
    @Resource
    private SubjectESService subjectESService;
    @Resource
    private UserRpc userRpc;
    public void add(SubjectInfoBO subjectInfoBO) {
        if (log.isInfoEnabled()) {
            log.info("SubjectDomainInfoServiceImpl.add.bo:{}", JSON.toJSONString(subjectInfoBO));
        }
        SubjectInfo subjectInfo = SubjectInfoConverter.INSTANCE.convertBoToInfo(subjectInfoBO);
//        设置默认为未删除
        subjectInfo.setIsDeleted(IsDeletedEnum.UN_DELETED.getCode());
        SubjectInfo insertedSubjectInfo = subjectInfoService.insert(subjectInfo);
        subjectInfoBO.setId(insertedSubjectInfo.getId());
        int type = subjectInfo.getSubjectType();

        //根据SubjectType识别Handler类型
        List<SubjectMapping> subjectMappingList = new LinkedList<>();
            /*
                这里的业务为：将subject_mapping表将info表、category表和label表进行逻辑关联
             */
        subjectInfoBO.getCategoryIds().forEach(categoryId -> {
            subjectInfoBO.getLabelIds().forEach(labelId -> {
                SubjectMapping subjectMapping = new SubjectMapping();
                subjectMapping.setSubjectId(subjectInfoBO.getId());
                subjectMapping.setCategoryId(categoryId);
                subjectMapping.setLabelId(labelId);
                subjectMapping.setIsDeleted(IsDeletedEnum.UN_DELETED.getCode());
                subjectMappingList.add(subjectMapping);
            });
        });
        subjectMappingService.insertBatch(subjectMappingList);
//        if (type == 4) {
//            //简答题目的插入
//
//            //获得info表的id即subjectId;
//            String subjectAnswer = subjectInfoBO.getSubjectAnswer();
//            SubjectBrief subjectBrief = new SubjectBrief();
//            subjectBrief.setSubjectAnswer(subjectAnswer);
//            subjectBrief.setSubjectId(subjectInfoBO.getId());
//            subjectInfo.setIsDeleted(0);
//            subjectBriefService.add(subjectBrief);
//            return;
//        }
            /*
                实现工厂加策略模式，新建SubjectTypeHandler接口，然后让4种题目类型实现这种接口 让后续的扩展就只需实现接口即可

             */
        SubjectTypeHandler handler = subjectTypeHandlerFactory.getHandler(subjectInfo.getSubjectType());
        handler.add(subjectInfoBO);


    }

    @Override
    public PageResult<SubjectInfoBO> getSubjectPage(SubjectInfoBO subjectInfoBO) {
        PageResult<SubjectInfoBO> result = new PageResult<>();
        result.setPageNo(subjectInfoBO.getPageNo());
        result.setPageSize(subjectInfoBO.getPageSize());
        Integer start = (subjectInfoBO.getPageNo() - 1) * subjectInfoBO.getPageSize();
        SubjectInfo subjectInfo = SubjectInfoConverter.INSTANCE.convertBoToInfo(subjectInfoBO);
        int count = subjectInfoService.countByCondition(subjectInfo, subjectInfoBO.getCategoryId(), subjectInfoBO.getLabelId());

        if (count == 0) {
            return result;
        }

        List<SubjectInfo> subjectInfoList = subjectInfoService.queryPage(subjectInfo, subjectInfoBO.getCategoryId(),
                subjectInfoBO.getLabelId(), start, subjectInfoBO.getPageSize());

        List<SubjectInfoBO> res = SubjectInfoConverter.INSTANCE.convertListInfoToBO(subjectInfoList);
        res.forEach(info->{
            SubjectMapping subjectMapping = new SubjectMapping();
            subjectMapping.setSubjectId(info.getId());
            List<SubjectMapping> subjectMappingList = subjectMappingService.queryLabelId(subjectMapping);
            List<Integer> LableIdList = subjectMappingList.stream().map(SubjectMapping::getLabelId).collect(Collectors.toList());
            List<SubjectLabel> subjectLabelList = subjectLabelService.batchQueryById(LableIdList);
            List<String> labelNameList = subjectLabelList.stream().map(SubjectLabel::getLabelName).collect(Collectors.toList());
            info.setLabelName(labelNameList);
        });
        result.setResult(res);
        result.setTotal(count);
        return result;
    }

    @Override
    public SubjectInfoBO querySubjectInfo(SubjectInfoBO subjectInfoBO) {
        if (log.isInfoEnabled()) {
            log.info("querySubjectInfo:{}", JSON.toJSONString(subjectInfoBO));
        }

        SubjectInfo subjectInfo = subjectInfoService.queryById(subjectInfoBO.getId());
        SubjectInfoBO subjectInfoBO1 =  SubjectInfoConverter.INSTANCE.convertInfoToBO(subjectInfo);
        SubjectTypeHandler handler = subjectTypeHandlerFactory.getHandler(subjectInfo.getSubjectType());
        SubjectInfoBO query = handler.query(subjectInfo.getId());

        SubjectMapping subjectMapping = new SubjectMapping();
        subjectMapping.setSubjectId(subjectInfoBO.getId());
        subjectMapping.setIsDeleted(IsDeletedEnum.UN_DELETED.getCode());
        List<SubjectMapping> subjectMappings = subjectMappingService.queryLabelId(subjectMapping);
        List<Integer> collect = subjectMappings.stream().map(SubjectMapping::getLabelId).collect(Collectors.toList());
        List<SubjectLabel> labelList = subjectLabelService.batchQueryById(collect);
        List<String> labelName = labelList.stream().map(SubjectLabel::getLabelName).collect(Collectors.toList());

        subjectInfoBO1.setOptionList(query.getOptionList());
        subjectInfoBO1.setSubjectAnswer(query.getSubjectAnswer());
        subjectInfoBO1.setLabelName(labelName);
        return subjectInfoBO1;
    }

    @Override
    public PageResult<SubjectInfoES> getSubjectPageBySearch(SubjectInfoBO subjectInfoBO) {
        SubjectInfoES subjectInfoES = new SubjectInfoES();
        subjectInfoES.setKeyWord(subjectInfoBO.getKeyWord());
        subjectInfoES.setPageNo(subjectInfoBO.getPageNo());
        subjectInfoES.setPageSize(subjectInfoBO.getPageSize());
        return subjectESService.querySubjectList(subjectInfoES);
    }

    @Override
    public List<SubjectInfoBO> getContributeList() {
        List<SubjectInfo> result = subjectInfoService.getContributeCount();
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        List<SubjectInfoBO> boList = new ArrayList<>();
        result.forEach((subjectInfo) ->{
            SubjectInfoBO subjectInfoBO = new SubjectInfoBO();
            subjectInfoBO.setSubjectCount(subjectInfo.getSubjectCount());
            UserInfo userInfo = userRpc.getUserInfo(subjectInfo.getCreatedBy());
            subjectInfoBO.setCreateUserAvatar(userInfo.getAvatar());
            boList.add(subjectInfoBO);

        });
        return boList;
    }

}
